<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AI形成性评价</title>
    <!-- 引入Vue2 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <style>
      /* 标题区域 */
      .header {
        text-align: center;
        padding-bottom: 8px;
      }
      .header h1 {
        margin: 0;
        color: #2c3e50;
        font-size: 26px; /* 页面主标题增大 */
      }
      .borderCon{
        height: 2px;
        margin-bottom: 20px;
        width: 100%;
        background-size: 20px 20px;
        background-image: linear-gradient(45deg, 
          #00cc99 25%,  
          #E5FAF5 25%,  
          #E5FAF5 50%,  
          #00cc99 50%,  
          #00cc99 75%,  
          #E5FAF5 75%   
        );
      }

      .medical-evaluation {
        font-family: "Microsoft YaHei", sans-serif;
        max-width: 800px;
        margin: 0 auto;
        padding: 10px 10px 32px;
        line-height: 1.6;
        color: #333;
      }

      .evaluation-container {
        background-color: #f9f9f9;
        border-radius: 10px;
        padding: 10px 20px 35px;
        min-height: 400px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }

      #chat-box {
        min-height: 300px;
      }

      /* 加载状态容器 - 位于内容下方 */
      .loading-container {
        height: 30px;
        display: flex;
        align-items: center;
        margin-top: 10px;
        margin-bottom: 10px;
      }

      /* 段落样式 */
      .paragraph {
        margin: 16px 0;
        text-indent: 20px;
        text-align: justify;
        font-size: 16px; /* 基础文本大小 */
      }

      /* 标题下划线容器 - 核心新增样式 */
      .title-wrapper {
        position: relative;
        margin-bottom: 16px; /* 下划线与下方内容的间距 */
      }
      
      /* 标题下划线样式 - 核心新增样式 */
      .title-underline {
      }

      /* 一级标题样式 - 显著增大 */
      .level-1 {
        font-size: 20px; /* 大幅增大 */
        font-weight: 600;
        color: #34495e;
        margin: 28px 0 0; /* 去除底部margin，由wrapper控制 */
        padding-bottom: 6px;
      }

      /* 二级标题样式 - 显著增大 */
      .level-2 {
        font-size: 20px; /* 大幅增大 */
        font-weight: 600;
        /* color: pink; */
        color: #34495e;
        margin: 24px 0 0; /* 去除底部margin，由wrapper控制 */
        padding-left: 8px;
        border-left: 3px solid #00cc99;
      }

      /* 三级标题样式 - 显著增大 */
      .level-3 {
        font-size: 20px; /* 大幅增大 */
        font-weight: 600;
        /* color: red; */
        color: #34495e;
        border-bottom: 1px solid #00cc99;
        padding-bottom: 2px;
        margin: 20px 0 0; /* 去除底部margin，由wrapper控制 */
      }

      /* 四级标题样式 */
      .level-4 {
        font-size: 18px;
        font-weight: 600;
        color: #34495e;
        margin: 18px 0 0; /* 去除底部margin，由wrapper控制 */
      }

      /* 五级标题样式 */
      .level-5 {
        font-size: 16px;
        font-weight: 600;
        color: #34495e;
        /* color: green; */
        margin: 16px 0 0; /* 去除底部margin，由wrapper控制 */
      }

      /* 列表项样式 */
      .list-item {
          margin: 8px 0 8px 0px;
          position: relative;
          padding-left: 0px;
          text-indent: 34px;
          font-size: 16px;
      }

      .list-item::before {
        content: "";
        position: absolute;
        left: 18px;
        top: 7px;
        line-height: 1;
        font-size: 38px !important;
        font-weight: 600;
        background: #00CC99;
        height: 10px;
        width: 10px;
        border-radius: 20px;
      }

      /* 加粗文本样式 */
      .500-text {
        font-weight: 600;
      }

      /* 注意事项样式 */
      .note {
        font-style: italic;
        color: #7f8c8d;
        padding: 10px 15px;
        background-color: #f8f9fa;
        border-radius: 5px;
        margin: 15px 0;
      }

      /* 打字光标动画 */
      .typing-cursor {
        display: inline-block;
        width: 10px;
        height: 18px;
        background-color: #00cc99;
        animation: blink 1s infinite;
      }

      /* 加载状态 */
      .loading-indicator {
        display: inline-block;
        width: 16px;
        height: 16px;
        border: 3px solid rgba(0, 204, 153, 0.3);
        border-radius: 50%;
        border-top-color: #00cc99;
        animation: spin 1s ease-in-out infinite;
        margin-right: 8px;
      }
      @keyframes spin {
        to {
          transform: rotate(360deg);
        }
      }

      @keyframes blink {
        0%,
        100% {
          opacity: 1;
        }
        50% {
          opacity: 0;
        }
      }

      .error {
        color: #FF4848;
        padding: 10px;
        background-color: #f8d7da;
        border-radius: 5px;
        margin: 10px 0;
      }
    </style>
  </head>
  <body>
    <div id="app" class="medical-evaluation">
      <div class="header">
        <h1>{{ examName }}</h1>
      </div>
      <div class='borderCon'></div>
      <div class="evaluation-container">
        <div id="chat-box">
          <!-- 内容区域 -->
          <div v-html="renderedContent"></div>
          <!-- 加载容器，位于内容下方 -->
          <div class="loading-container" v-if="isLoading">
            <div class="loading-indicator"></div>
            <span>正在生成评价内容...</span>
          </div>
        </div>
      </div>
    </div>

    <script>
      new Vue({
        el: "#app",
        data() {
          return {
            AppConfig: {
              API_ENDPOINTS: {
                CONTENT: "https://sa.solacemeta.com/platform-api/app/huoshan/aiContent",
                CHAT_COMPLETION: "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
              },
              AI_MODEL: "doubao-seed-1-6-250615",
              AUTH_TOKEN: "Bearer fc9b5fc8-01dc-4ab9-ba20-29c0322c7bdd",
              REQUIRED_PARAMS: ["token", "examinationId"],
            },
            renderedContent: "",
            isLoading: true,
            fullMessage: "",
            currentParagraph: "",
            examName: ""
          }
        },
        mounted() {
          this.init()
        },
        methods: {
          async init() {
            try {
              this.isLoading = true
              const urlParams = this.parseUrlParams()
              this.validateParams(urlParams)
              this.examName = urlParams.examName || "AI形成性评价"
              
              const contentData = await this.fetchContentData(urlParams)
              if (!contentData.content) {
                throw new Error("内容数据不完整")
              }

              const messages =  {
                model: this.AppConfig.AI_MODEL,
                stream: true,
                messages: [
                  {
                    role: "user",
                    content: contentData.content,
                  },
                ],
                thinking: {
                  type: "disabled",
                },
              }
              await this.streamChat(messages)
            } catch (error) {
              this.handleError(error)
            }
          },

          handleError(error) {
            this.renderedContent = `<div class="error">发生错误: ${error.message}</div>`
            this.isLoading = false
            console.error("错误:", error)
          },

          async fetchContentData(params) {
            try {
              const response = await fetch(this.AppConfig.API_ENDPOINTS.CONTENT, {
                method: "POST",
                headers: {
                  "Content-Type": "application/json",
                  token: params.token,
                },
                body: JSON.stringify({
                  examinationId: params.examinationId,
                }),
              })
              return this.handleResponse(response)
            } catch (error) {
              throw new Error(`获取内容失败: ${error.message}`)
            }
          },

          async handleResponse(response) {
            if (!response.ok) {
              throw new Error(`HTTP错误: ${response.status} ${response.statusText}`)
            }

            const data = await response.json()
            if (!data || typeof data !== "object") {
              throw new Error("接口返回格式不正确")
            }
            return data
          },

          parseUrlParams() {
            const params = {}
            const queryString = window.location.search.slice(1)

            if (queryString) {
              queryString.split("&").forEach(pair => {
                const [key, value] = pair.split("=")
                if (key) {
                  params[key] = decodeURIComponent(value || "")
                }
              })
            }
            return params
          },

          validateParams(params) {
            const missingParams = this.AppConfig.REQUIRED_PARAMS.filter(param => !params[param])
            if (missingParams.length > 0) {
              throw new Error(`缺少必要参数: ${missingParams.join(", ")}`)
            }
          },
          
          async streamChat(messages) {
            try {
              const response = await fetch(this.AppConfig.API_ENDPOINTS.CHAT_COMPLETION, {
                method: "POST",
                headers: {
                  "Content-Type": "application/json",
                  Authorization: this.AppConfig.AUTH_TOKEN,
                },
                body: JSON.stringify(messages),
              })

              if (!response.ok) {
                throw new Error(`HTTP错误: ${response.status}`)
              }

              const reader = response.body.getReader()
              const decoder = new TextDecoder()

              while (true) {
                const { done, value } = await reader.read()
                if (done) {
                  if (this.currentParagraph.trim()) {
                    this.fullMessage += this.formatContent(this.currentParagraph)
                  }
                  this.renderedContent = this.fullMessage
                  this.isLoading = false
                  break
                }

                const chunk = decoder.decode(value)
                this.processChunk(chunk)
              }
            } catch (error) {
              this.handleError(error)
            }
          },
          
          processChunk(chunk) {
            chunk.split("\n").forEach(line => {
              if (line.startsWith("data: ")) {
                try {
                  const data = JSON.parse(line.slice(6))
                  if (data.choices?.[0]?.delta?.content) {
                    const newContent = data.choices[0].delta.content
                    this.processNewContent(newContent)
                  }
                } catch (e) {
                  if (!line.includes("[DONE]")) {
                    console.warn("解析数据块失败:", e)
                  }
                }
              }
            })
          },
          
          processNewContent(content) {
            if (content.includes("\n")) {
              const parts = content.split("\n")
              for (let i = 0; i < parts.length - 1; i++) {
                this.currentParagraph += parts[i]
                this.fullMessage += this.formatContent(this.currentParagraph)
                this.currentParagraph = ""
              }
              this.currentParagraph += parts[parts.length - 1]
            } else {
              this.currentParagraph += content
            }

            this.renderedContent = this.fullMessage + this.formatContent(this.currentParagraph, true)
            this.scrollToBottom()
          },
          
          formatContent(content, isTemporary = false) {
            if (!content.trim()) return ""

            let formatted = content;
            
            // 强化标题识别，为每个标题添加下划线容器
            // 处理一级标题（# 或中文数字标题）
            formatted = formatted.replace(
              /^#{1}\s+(.*?)$/gm, 
              '</div><div class="title-wrapper"><div class="level-1">$1</div><div class="title-underline"></div></div>'
            );
            formatted = formatted.replace(
              /^(一|二|三|四|五|六|七|八|九|十)、\s*(.*?)$/gm, 
              '</div><div class="title-wrapper"><div class="level-1">$1、$2</div><div class="title-underline"></div></div>'
            );
            
            // 处理二级标题（##）
            formatted = formatted.replace(
              /^#{2}\s+(.*?)$/gm, 
              '</div><div class="title-wrapper"><div class="level-2">$1</div><div class="title-underline"></div></div>'
            );
            
            // 处理三级标题（###）
            formatted = formatted.replace(
              /^#{3}\s+(.*?)$/gm, 
              '</div><div class="title-wrapper"><div class="level-3">$1</div><div class="title-underline"></div></div>'
            );

            // 处理四级标题（####）
            formatted = formatted.replace(
              /^#{4}\s+(.*?)$/gm, 
              '</div><div class="title-wrapper"><div class="level-4">$1</div><div class="title-underline"></div></div>'
            );

            // 处理五级标题（#####）
            formatted = formatted.replace(
              /^#{5}\s+(.*?)$/gm, 
              '</div><div class="title-wrapper"><div class="level-5">$1</div><div class="title-underline"></div></div>'
            );

            // 处理加粗文本
            formatted = formatted.replace(/\*\*(.*?)\*\*/g, '<span class="500-text">$1</span>');

            // 处理列表项
            formatted = formatted.replace(/-(?=\s)/g, '</div><div class="list-item">');

            // 处理段落
            if (
              !formatted.startsWith('<div class="title-wrapper">') &&
              !formatted.startsWith('<div class="list-item">')
            ) {
              formatted = `<div class="paragraph">${formatted}</div>`;
            }

            return formatted;
          },
          
          scrollToBottom() {
            this.$nextTick(() => {
              const chatBox = document.getElementById("chat-box")
              if (chatBox) {
                chatBox.scrollTop = chatBox.scrollHeight
              }
            })
          },
        },
      })
    </script>
  </body>
</html>